﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.IO;
using PokerClient.Connection.Interfaces;
using PokerClient.Connection.CommandHandlers;
using PokerClient.Connection.Protocols;
using PokerClient.VisualDisp;
using System.Runtime.InteropServices;

namespace PokerClient
{
	public class Client
	{
		TcpClient client;
		NetworkStream clientStream;
		StreamReader clientRead;
		StreamWriter clientWrite;
		Thread t;
		Boolean flag,active;
		MainWindow window;
		Lobby lobby;
		IChangeWindow currWindow;
		CommandHandler handler;
		ManualResetEvent mre = new ManualResetEvent(false);
		String uname,table,seat,chips,pword;
		Dictionary<String, TableIdent> tablelist = new Dictionary<String, TableIdent>();
		const String SERVER_ADD = "84.94.24.167";//"10.0.0.2"; // //"finalprojakoe.servegame.com";
		const int SERVER_PORT = 9999;
		private Table tTable;

		public Client(MainWindow window)
		{
			this.window = window;
			this.init();
			Wind32.AllocConsole();
		}

		private void init()
		{
			this.client = new TcpClient();
			this.handler = new CommandHandler(this.window,this);
			this.t = new Thread(new ThreadStart(work));
			this.t.IsBackground = true;
			this.flag = true;
			
		}

		public void go()
		{
			this.t.Start();
		}

		public void reset()
		{
			this.stop();
			this.init();
			
		}
		private void work()
		{
			try
			{
				this.client.Connect(SERVER_ADD, SERVER_PORT);
				this.clientStream = this.client.GetStream();
				this.clientRead = new StreamReader(this.clientStream);
				this.clientWrite = new StreamWriter(this.clientStream);
				this.active = true;
				while (flag)
				{
					String t = " ";
					if (this.clientStream.DataAvailable)
						t = this.clientRead.ReadLine();
					if (t != null && t != " ")
					{
						Console.WriteLine(t);
						this.handler.assignCommand(t);
						this.handler.analyze();
						FilePrint.writeBugtofile("IN:" + t + "\r\n");
						
					}
					Thread.Sleep(100);
				}

			}
			catch (System.Exception ex)
			{
				this.currWindow.updateStatus(ex.Message);
			}
			finally
			{
				this.close();
				mre.Set();
				this.active = false;
			}
		}
		public void stop()
		{
			this.flag = false;
			mre.WaitOne(1000);
		}

		private void close()
		{
			try
			{
				this.clientRead.Close();
				this.clientWrite.Close();
				this.clientStream.Close();
				this.client.Close();
			}
			catch (System.Exception ex)
			{
				(this.currWindow).updateStatus(ex.Message);
			}
		}

		public void sent(String msg)
		{
			try
			{
				this.clientWrite.WriteLine(msg);
				this.clientWrite.Flush();
				Console.WriteLine(msg);
				if (msg.Equals("QUIT"))
					this.flag = false;
				FilePrint.writeBugtofile("OUT:" + msg + "\r\n");
			}
			catch (System.Exception ex)
			{
				(this.window).updateStatus(ex.Message);
			}
		}
		public void auth(String user,String password)
		{
			String auther = ProtocolsSignInSignUp.PROTOCOL_AUTH_SIGNIN(user, password);
			this.sent(auther);

		}
		public void reg(String user,String password)
		{
			String s = PokerClient.Connection.Protocols.ProtocolsSignInSignUp.PROTOCOL_AUTH_SIGNUP(user, password);
			sent(s);
		}
		public String usern
		{
			set
			{
				this.uname = value;

			}
			get
			{
				return this.uname;
			}
		}
		public String chip
		{
			set
			{
				this.chips = value;

			}
			get
			{
				return this.chips;
			}
		}
		public String pass
		{
			set
			{
				this.pword = value;
			}
		}
		public Dictionary<String,TableIdent> tableList
		{
			set
			{
				this.tablelist = value;
			}
			get
			{
				return this.tablelist;
			}
		}
		public Lobby assignLoby {
			get
			{
				return this.lobby;
			} 
			set
			{
				this.lobby = value;
				this.handler.assignLobby(this.lobby);
			} 
		}
		public Table assignTable
		{
			set
			{
				this.tTable = value;
				this.handler.assiginTable((this.tTable));
			}
			get
			{
				return this.tTable;
			}
		}
		public IChangeWindow currentWindow
		{
			set
			{
				this.currWindow = value;
			}
		}

		public string sSeat
		{
			get
			{
				return this.seat;
			}
			set
			{
				this.seat = value;
			}
		}
		public Boolean isActive
		{
			get
			{
				return this.active;
			}
		}
		public string sTable 
		{
			get
			{
				return this.table;
			}
			set
			{
				this.table = value;
			}
		}
	}
	public class Wind32
	{
		[DllImport("kernel32.dll")]
		public static extern Boolean AllocConsole();
		[DllImport("kernel32.dll")]
		public static extern Boolean FreeConsole();
	}	
}
